package com.example.my_music_palyer.controller;

import com.example.my_music_palyer.common.tools.Mp3Agic;
import com.example.my_music_palyer.model.Music;
import com.example.my_music_palyer.model.User;
import com.example.my_music_palyer.service.LoveMusicService;
import com.example.my_music_palyer.service.MusicService;
import com.example.my_music_palyer.common.tools.Constant;
import com.example.my_music_palyer.common.tools.Mp3Tag;
import com.example.my_music_palyer.common.tools.ResponseBodyMessage;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.UnsupportedTagException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@RequestMapping("/music")
@RestController
@ResponseBody
@CrossOrigin
public class MusicController {


    /**
     * 此处可以使用 Value 注解获取到 配置文件中的路径
     *
     * @Value("${music.local.path}")
     */

    /*线上
    private static String SAVE_PATH = "/my_m/musicData/";
    线下
    private static String SAVE_PATH = "E:/JAVACODE/music/musicData/";*/
    @Value("${music.local.path}")
    private String SAVE_PATH;
    @Autowired
    MusicService musicService;

    @Autowired
    LoveMusicService loveMusicService;

    @Autowired
    Mp3Agic mp3Agic;

    @RequestMapping("/upload")
    public ResponseBodyMessage<Boolean> upload(String singer,
                                               @RequestParam("filename") MultipartFile file,
                                               HttpServletRequest req, HttpServletResponse resp) throws IOException, InvalidDataException, UnsupportedTagException {
        //检测是否登录
        HttpSession session = req.getSession(false);
        if (session == null || session.getAttribute(Constant.USERINFO_SESSION_KEY) == null) {
            return new ResponseBodyMessage<>(-1, "请登陆后在上传", false);
        }

        //上传文件
        String fileNameAndType = file.getOriginalFilename();//xxx.mp3
        //System.out.println("fileNameAndType:" + fileNameAndType);
        //在歌曲名称中添加作者名
        String path = SAVE_PATH + singer + "=" + fileNameAndType;

        //System.out.println(path);
        File dest = new File(path);

        //System.out.println(dest.getPath());

        if (!dest.exists()) {
            dest.mkdirs();
        }

        try {
            file.transferTo(dest);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        //判断 是否 是 mp3 文件
        if (!mp3Agic.isMp3(path)) {
            dest.delete();
            return new ResponseBodyMessage<>(-2, "文件不是MP3格式", false);
        }


        //获取歌曲名称
        String title = fileNameAndType.substring(0, fileNameAndType.lastIndexOf("."));
        //格式化时间
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String time = sf.format(new Date());

        String url = "/music/get?path=" + singer + "=" + title;

        User user = (User) req.getSession().getAttribute(Constant.USERINFO_SESSION_KEY);
        int userId = user.getId();

        //查看数据库中是否有相同作者的歌曲
        Music dataMusic = musicService.isSymple(title, singer);
        if (dataMusic != null && dataMusic.getTitle().equals(title) && dataMusic.getSinger().equals(singer)) {
            dest.delete();
            return new ResponseBodyMessage<>(-3, "歌曲已经存在！", false);
        }

        // 默认设置为审核中状态（2）
        int ret = musicService.insert(title, singer, time, url, userId, 2);

        if (ret == 1) {
            //数据库上传成功
            System.out.println(singer + "=" + title + "上传成功!");
            resp.sendRedirect("/list.html");
        } else {
            //数据库上传失败
            //需要删除上传本地文件
            System.out.println("上传失败，删除本地文件!" + dest);

            dest.delete();
            return new ResponseBodyMessage<>(-1, "上传失败!", false);
        }
        return new ResponseBodyMessage<>(200, "上传成功!", true);

    }

    @RequestMapping("/get")
    public ResponseEntity get(String path, HttpServletRequest req) {
        // 权限拦截：仅上架(1)可被普通用户播放；管理员可播放任意状态
        // 根据URL还原数据库中的url字段值
        String url = "/music/get?path=" + path.substring(0, path.lastIndexOf(".mp3")) ;
        Music music = musicService.findByUrl(url);

        if (music != null) {
            HttpSession session = req.getSession(false);
            User user = (session != null) ? (User) session.getAttribute(Constant.USERINFO_SESSION_KEY) : null;
            boolean isAdmin = (user != null && "admin".equals(user.getRole()));
            if (!isAdmin && music.getStatus() != 1) {
                return ResponseEntity.status(403).build();
            }
        }

        File file = new File(SAVE_PATH + path);
        byte[] a = null;
        try {
            a = Files.readAllBytes(file.toPath());
            if (a == null) {
                return ResponseEntity.badRequest().build();
            }
            return ResponseEntity.ok(a);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 删除单个音乐 - 仅管理员可用
     *
     * @param id
     * @return
     */
    @RequestMapping("/delete")
    public ResponseBodyMessage<Boolean> deleteById(@RequestParam String id, HttpServletRequest req) throws IOException {
        // 检查用户权限
        HttpSession session = req.getSession(false);
        if (session == null || session.getAttribute(Constant.USERINFO_SESSION_KEY) == null) {
            return new ResponseBodyMessage<>(-1, "请先登录", false);
        }
        
        User user = (User) session.getAttribute(Constant.USERINFO_SESSION_KEY);
        if (!"admin".equals(user.getRole())) {
            return new ResponseBodyMessage<>(-1, "权限不足，仅管理员可删除音乐", false);
        }

        int nowid = Integer.parseInt(id);
        Music music = musicService.findMusicById(nowid);
        if (music == null) {
            return new ResponseBodyMessage<>(-1, "您所要删除的音乐不存在", false);
        }
        int ret = musicService.deleteMusicById(nowid);
        if (ret == 1) {
            //数据库音乐删除成功
            //删除 服务器本地文件
            int index = music.getUrl().indexOf("=");
            String fileName = music.getUrl().substring(index + 1);
            File file = new File(SAVE_PATH + fileName + ".mp3");

            boolean isDelete = file.delete();
            System.out.println(isDelete);
            System.out.println("————————————————————");

            if (isDelete) {
                loveMusicService.deleteLoveMusicByMusicId(nowid);
                return new ResponseBodyMessage<>(200, "服务器音乐删除成功", true);
            } else {
                return new ResponseBodyMessage<>(-1, "服务器音乐删除失败", false);
            }
        } else {
            //数据库音乐删除失败
            return new ResponseBodyMessage<>(-1, "数据库删除失败，请联系管理员", false);
        }
    }

    /**
     * 批量删除音乐 - 仅管理员可用
     */
    @RequestMapping("/deleteSel")
    public ResponseBodyMessage<Boolean> deleteSelMusic(@RequestParam("id[]") List<Integer> id, HttpServletRequest req) {
        // 检查用户权限
        HttpSession session = req.getSession(false);
        if (session == null || session.getAttribute(Constant.USERINFO_SESSION_KEY) == null) {
            return new ResponseBodyMessage<>(-1, "请先登录", false);
        }
        
        User user = (User) session.getAttribute(Constant.USERINFO_SESSION_KEY);
        if (!"admin".equals(user.getRole())) {
            return new ResponseBodyMessage<>(-1, "权限不足，仅管理员可删除音乐", false);
        }

        int sum = 0;
        for (int i = 0; i < id.size(); i++) {
            int musicId = id.get(i);

            Music music = musicService.findMusicById(musicId);
            if (music == null) {
                return new ResponseBodyMessage<>(-1, "您所要删除的音乐不存在", false);
            }

            int ret = musicService.deleteMusicById(musicId);
            if (ret == 1) {
                //数据库音乐删除成功
                //删除 服务器本地文件
                loveMusicService.deleteLoveMusicByMusicId(musicId);
                int index = music.getUrl().indexOf("=");
                String fileName = music.getUrl().substring(index + 1);
                File file = new File(SAVE_PATH + fileName + ".mp3");
                System.out.println(file);
                if (file.delete()) {
                    sum += ret;
                } else {
                    return new ResponseBodyMessage<>(-1, "服务器音乐删除失败", false);
                }
            } else {
                //数据库音乐删除失败
                return new ResponseBodyMessage<>(-1, "删除失败，请联系管理员", false);
            }

        }
        if (sum == id.size()) {
            return new ResponseBodyMessage<>(200, "批量删除成功", true);
        } else {
            return new ResponseBodyMessage<>(-1, "批量删除失败", false);
        }
    }

    @RequestMapping("/findMusic")
    public ResponseBodyMessage<List<Music>> findMusic(@RequestParam(required = false) String musicName, HttpServletRequest req) {
        List<Music> music = null;
        HttpSession session = req.getSession(false);
        Integer userId = null;
        if (session != null && session.getAttribute(Constant.USERINFO_SESSION_KEY) != null) {
            User user = (User) session.getAttribute(Constant.USERINFO_SESSION_KEY);
            if (user != null) {
                userId = user.getId();
            }
        }

        if (musicName == null) {
            if (userId != null) {
                music = musicService.findMusicForUser(userId);
            } else {
                music = musicService.findMusic();
            }
        } else {
            if (userId != null) {
                music = musicService.findMusicByMusicNameForUser(userId, musicName);
            } else {
                music = musicService.findMusicByMusicName(musicName);
            }
        }
        return new ResponseBodyMessage<>(200, "查询到歌曲信息！", music);
    }

    /**
     * 管理员查询所有音乐（包括下架状态）
     */
    @RequestMapping("/findAllMusic")
    public ResponseBodyMessage<List<Music>> findAllMusic(@RequestParam(required = false) String musicName, HttpServletRequest req) {
        // 检查用户权限
        HttpSession session = req.getSession(false);
        if (session == null || session.getAttribute(Constant.USERINFO_SESSION_KEY) == null) {
            return new ResponseBodyMessage<>(-1, "请先登录", null);
        }
        
        User user = (User) session.getAttribute(Constant.USERINFO_SESSION_KEY);
        if (!"admin".equals(user.getRole())) {
            return new ResponseBodyMessage<>(-1, "权限不足，仅管理员可查看所有音乐", null);
        }

        List<Music> music = null;
        if (musicName == null) {
            music = musicService.findAllMusic();
        } else {
            music = musicService.findAllMusicByMusicName(musicName);
        }
        return new ResponseBodyMessage<>(200, "查询到所有歌曲信息！", music);
    }

    /**
     * 更新音乐状态（上架/下架）- 仅管理员可用
     */
    @RequestMapping("/updateStatus")
    public ResponseBodyMessage<Boolean> updateMusicStatus(@RequestParam String id, @RequestParam String status, HttpServletRequest req) {
        // 检查用户权限
        HttpSession session = req.getSession(false);
        if (session == null || session.getAttribute(Constant.USERINFO_SESSION_KEY) == null) {
            return new ResponseBodyMessage<>(-1, "请先登录", false);
        }
        
        User user = (User) session.getAttribute(Constant.USERINFO_SESSION_KEY);
        if (!"admin".equals(user.getRole())) {
            return new ResponseBodyMessage<>(-1, "权限不足，仅管理员可修改音乐状态", false);
        }

        int musicId = Integer.parseInt(id);
        int musicStatus = Integer.parseInt(status);
        
        if (musicStatus != 0 && musicStatus != 1) {
            return new ResponseBodyMessage<>(-1, "状态值无效", false);
        }

        int ret = musicService.updateMusicStatus(musicId, musicStatus);
        if (ret == 1) {
            String statusText = musicStatus == 1 ? "上架" : "下架";
            return new ResponseBodyMessage<>(200, "音乐" + statusText + "成功", true);
        } else {
            return new ResponseBodyMessage<>(-1, "状态更新失败", false);
        }
    }
}